package saxion.speelveld.spaceengineer.database;

import java.util.ArrayList;

import saxion.speelveld.spaceengineer.buildings.Factory;
import saxion.speelveld.spaceengineer.buildings.GreenHouse;
import saxion.speelveld.spaceengineer.buildings.MeatLab;
import saxion.speelveld.spaceengineer.buildings.Mines;
import saxion.speelveld.spaceengineer.buildings.OreRefinery;
import saxion.speelveld.spaceengineer.buildings.Powerplant;
import saxion.speelveld.spaceengineer.buildings.RecreationCenter;
import saxion.speelveld.spaceengineer.buildings.ResearchLab;
import saxion.speelveld.spaceengineer.buildings.SolarCenter;
import saxion.speelveld.spaceengineer.buildings.SpaceCenter;
import saxion.speelveld.spaceengineer.buildings.SpaceCube;
import saxion.speelveld.spaceengineer.buildings.SpaceMarket;
import saxion.speelveld.spaceengineer.buildings.SpaceSchool;
import saxion.speelveld.spaceengineer.buildings.WareHouses;
import saxion.speelveld.spaceengineer.buildings.WaterPurificator;
import saxion.speelveld.spaceengineer.model.Building;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

public class BuildingDAO
{
	private SQLiteDatabase database;

	private BuildingDB dbHelper;

	private BuildingTypeDAO buildingTypeDatasource;

	public BuildingDAO(Context context)
	{
		dbHelper = new BuildingDB(context);
		buildingTypeDatasource = new BuildingTypeDAO(context);
	}

	/**
	 * Open the database connection.
	 * 
	 * @throws SQLException
	 */
	public void open() throws SQLException
	{
		database = dbHelper.getWritableDatabase();
	}

	/**
	 * Close the database connection.
	 */
	public void close()
	{
		dbHelper.close();
	}

	public ArrayList<Building> getAllBuildingsForGame(int gameId)
	{
		ArrayList<Building> listOfBuildings = new ArrayList<Building>();

		Log.i("getAllBuildingsForGame", "starting method.");

		// Cursor cursor = database.rawQuery("SELECT * FROM " + BuildingDB.TABLE_NAME
		// + " b INNER JOIN " + BuildingTypeDB.TABLE_NAME + " t ON b." + BuildingDB.COLUMN_BUILDINGTYPEID + " = t." +
		// BuildingTypeDB.COLUMN_ID + " WHERE b." + BuildingDB.COLUMN_GAMEID
		// + " = " + gameId, null);

		Cursor cursor = database.rawQuery("SELECT * FROM " + BuildingDB.TABLE_NAME +
			" WHERE " + BuildingDB.COLUMN_GAMEID + " = " + gameId, null);

		Log.i("getAllBuildingsForGame", "got cursor.");

		cursor.moveToFirst();

		buildingTypeDatasource.open();
		while (cursor.isAfterLast() == false)
		{
			listOfBuildings.add(cursorToBuilding(cursor, null));
			cursor.moveToNext();
		}
		buildingTypeDatasource.close();
		cursor.close();

		return listOfBuildings;
	}

	public Building getBuilding(int gameId, int arrayPosition)
	{
		Building building = null;

		// Log.w("getBuilding", "trying to get buildingid " + id);

		Cursor cursor = database.rawQuery("SELECT * FROM " + BuildingDB.TABLE_NAME + " WHERE " +
			BuildingDB.COLUMN_GAMEID + " = " + gameId + " AND " + BuildingDB.COLUMN_BUILDINGIDINGAME + " = "
			+ arrayPosition, null);

		cursor.moveToFirst();

		buildingTypeDatasource.open();
		if (cursor.getCount() == 1)
		{
			building = cursorToBuilding(cursor, null);
		}
		buildingTypeDatasource.close();
		cursor.close();
		return building;
	}

	public Building getBuilding(int buildingId, ArrayList<Building> buildingList)
	{
		Building building = null;

		//

		Cursor cursor = database.rawQuery("SELECT * FROM " + BuildingDB.TABLE_NAME + " WHERE " +
			BuildingDB.COLUMN_ID + " = " + buildingId, null);

		cursor.moveToFirst();
		// Log.w("getBuilding", "got " + cursor.getCount() + " rows of result");
		buildingTypeDatasource.open();
		if (cursor.getCount() == 1)
		{
			building = cursorToBuilding(cursor, buildingList);
		}
		buildingTypeDatasource.close();
		cursor.close();

		if (building == null)
		{
			// Log.w("getBuilding", "screw you you piece of gfuckagaskgja;lsgn a;l ;laskn");
		}

		return building;
	}

	private Building cursorToBuilding(Cursor cursor, ArrayList<Building> buildingList)
	{
		Building building = null;

		int buildingTypeId = cursor.getInt(cursor.getColumnIndex(BuildingDB.COLUMN_BUILDINGTYPEID));

		String buildingName = buildingTypeDatasource.getTypeNameById(buildingTypeId);

		int buildingLevel = cursor.getInt(cursor.getColumnIndex(BuildingDB.COLUMN_BUILDINGLEVEL));
		int buildingPointX = cursor.getInt(cursor.getColumnIndex(BuildingDB.COLUMN_BUILDINGPOINTX));
		int buildingPointY = cursor.getInt(cursor.getColumnIndex(BuildingDB.COLUMN_BUILDINGPOINTY));

		if (buildingList != null)
		{
			int buildingArrayPos = cursor.getInt(cursor.getColumnIndex(BuildingDB.COLUMN_BUILDINGIDINGAME));
			if (buildingArrayPos < buildingList.size())
			{
				return buildingList.get(buildingArrayPos);
			}
		}

		if (buildingName.equals("Factory"))
		{
			building = new Factory();
		}
		else if (buildingName.equals("Mines"))
		{
			building = new Mines();
		}
		else if (buildingName.equals("Green House"))
		{
			building = new GreenHouse();
		}
		else if (buildingName.equals("Meat Lab"))
		{
			building = new MeatLab();
		}
		else if (buildingName.equals("Mines"))
		{
			building = new Mines();
		}
		else if (buildingName.equals("Ore Refinery"))
		{
			building = new OreRefinery();
		}
		else if (buildingName.equals("Powerplant"))
		{
			building = new Powerplant();
		}
		else if (buildingName.equals("Recreation Center"))
		{
			building = new RecreationCenter();
		}
		else if (buildingName.equals("Research Lab"))
		{
			building = new ResearchLab();
		}
		else if (buildingName.equals("Solar Center"))
		{
			building = new SolarCenter();
		}
		else if (buildingName.equals("Space Center"))
		{
			building = new SpaceCenter();
		}
		else if (buildingName.equals("Space Cube"))
		{
			building = new SpaceCube();
		}
		else if (buildingName.equals("Space Market"))
		{
			building = new SpaceMarket();
		}
		else if (buildingName.equals("Space School"))
		{
			building = new SpaceSchool();
		}
		else if (buildingName.equals("Ware Houses"))
		{
			building = new WareHouses();
		}
		else if (buildingName.equals("Water Purificator"))
		{
			building = new WaterPurificator();
		}

		building.setBuildingLevel(buildingLevel);
		building.setBuildingPointInFieldX(buildingPointX);
		building.setBuildingPointInFieldY(buildingPointY);

		return building;

	}

	private boolean checkIfBuildingExists(int gameId, int arrayPosition)
	{
		boolean exists = false;
		Cursor cursor = database.rawQuery("SELECT * FROM " + BuildingDB.TABLE_NAME + " WHERE " +
			BuildingDB.COLUMN_GAMEID + " = " + gameId + " AND " + BuildingDB.COLUMN_BUILDINGIDINGAME + " = "
			+ arrayPosition, null);

		cursor.moveToFirst();
		if (cursor.getCount() == 1)
		{
			exists = true;
		}
		cursor.close();
		return exists;
	}

	public void putBuilding(int gameId, Building building, int arrayPosition)
	{

		ContentValues values = new ContentValues();
		values.put(BuildingDB.COLUMN_GAMEID, gameId);
		values.put(BuildingDB.COLUMN_BUILDINGLEVEL, building.getBuildingLevel());
		values.put(BuildingDB.COLUMN_BUILDINGPOINTX, building.getBuildingPointInFieldX());
		values.put(BuildingDB.COLUMN_BUILDINGPOINTY, building.getBuildingPointInFieldY());

		buildingTypeDatasource.open();
		int buildingTypeId = buildingTypeDatasource.GetTypeIdByName(building.getBuildingName());
		buildingTypeDatasource.close();
		values.put(BuildingDB.COLUMN_BUILDINGTYPEID, buildingTypeId);

		if (checkIfBuildingExists(gameId, arrayPosition) == false)
		{
			values.put(BuildingDB.COLUMN_BUILDINGIDINGAME, arrayPosition);
			Log.i("putBuilding", "new building.");
			Log.i("putBuilding", "buildingTypeId: " + buildingTypeId);

			int insertedId = (int) database.insert(BuildingDB.TABLE_NAME, null, values);
			building.setBuildingId(insertedId);
		}
		else
		{
			Log.i("putBuilding", "updating building.");
			database.update(BuildingDB.TABLE_NAME, values,
				BuildingDB.COLUMN_GAMEID + "=? AND " + BuildingDB.COLUMN_BUILDINGIDINGAME + "=?",
				new String[] { gameId + "", arrayPosition + "" });
		}
	}

	public boolean removeBuilding(int gameId, int arrayPosition, Building building)
	{
		int alteredRows = database.delete(BuildingDB.TABLE_NAME, BuildingDB.COLUMN_GAMEID + "=? AND "
			+ BuildingDB.COLUMN_BUILDINGIDINGAME + "=?", new String[] { gameId + "", arrayPosition + "" });

		if (alteredRows >= 1)
		{
			return true;
		}
		return false;
	}

	public void beginTransactionMode()
	{
		database.beginTransaction();
	}

	public void setTransactionModeSuccesfull()
	{
		database.setTransactionSuccessful();
	}

	public void endTransactionMode()
	{
		database.endTransaction();
	}
}
